package com.onpositive.wiki3.db.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;

import com.carrotsearch.hppc.IntOpenHashSet;
import com.onpositive.wiki3.db.ICategoryAccess;
import com.onpositive.wiki3.db.IWikiDB;

public class MajorTemplatesBuilder {

	private static HashSet<String> toIgnore = new HashSet<String>();
	static {
		toIgnore.add("reflist");
		toIgnore.add("convert");
		toIgnore.add("about");
		toIgnore.add("see also");
		toIgnore.add("citation");
		toIgnore.add("rquote");
		toIgnore.add("citation needed");
		toIgnore.add("coord");
		toIgnore.add("main");
		toIgnore.add("spaces");
		toIgnore.add("clear");
	}
	IWikiDB members;

	static class TemplateInfo implements Comparable<TemplateInfo> {
		String str;

		public TemplateInfo(String str) {
			super();
			this.str = str;
		}

		int count;
		IntOpenHashSet pages=new IntOpenHashSet();

		@Override
		public int compareTo(TemplateInfo o) {
			return o.count - this.count;
		}

		@Override
		public String toString() {
			return str + ":" + count;
		}
	}

	static class PageInfo implements Comparable<PageInfo> {

		int id;
		String title;

		public PageInfo(int id, String title, int count,
				Map<String, Integer> map) {
			super();
			this.id = id;
			this.title = title;
			this.count = count;
			this.templates = map;
		}

		int count;
		Map<String, Integer> templates;

		@Override
		public int compareTo(PageInfo o) {
			return o.count - this.count;
		}

		@Override
		public String toString() {
			return title + ":" + count;
		}

	}

	IntOpenHashSet smartBuildMembers(IWikiDB db, File fl) {
		this.members = db;
		
		ICategoryAccess categoryAccessor = members.getCategoryAccessor();
		int qa = 0;
		// HashMap<Integer, Integer> ms = new HashMap<Integer, Integer>();
		int[] doGet = members.getCategoryAccessor()
				.getAllCategoriesWithChilren();
		// System.out.println(ms.size());
		HashMap<String, TemplateInfo> msq = new HashMap<String, MajorTemplatesBuilder.TemplateInfo>();
		int size = members.getContentAccessor().size();
		for (int m = 0; m < size; m++) {

			boolean hasText = members.getContentAccessor().hasText(m);
			if (hasText) {
				String title = members.getTitleMapper().getTitle(m);

				PageInfo p = new PageInfo(m, title, 1,
						resolveTemplates(members.getContentAccessor()
								.getTextContent(m)));
				for (String s : p.templates.keySet()) {
					TemplateInfo templateInfo = msq.get(s);
					if (templateInfo == null) {
						templateInfo = new TemplateInfo(s);
						msq.put(s, templateInfo);
					}
					templateInfo.count +=1;
					templateInfo.pages.add(m);
				}
				if (m%10000==0){
					System.out.println(m+":"+msq.size());
				}

			}
		}

		ArrayList<TemplateInfo> zz = new ArrayList<MajorTemplatesBuilder.TemplateInfo>(
				msq.values());
		java.util.Collections.sort(zz);
		int pm = 0;
		// HashMap<String, >
		TemplateStorage ss=new TemplateStorage();
		ss.ids=new int[zz.size()][];
		ss.names=new String[zz.size()];
		int a=0;
		for (TemplateInfo t : zz) {
			System.out.println(t);
			ss.ids[a]=t.pages.toArray();
			ss.names[a]=t.str;
			a++;			
		}
		try {
			ss.write(fl.getAbsolutePath());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

	

	public static Map<String, Integer> resolveTemplates(String str) {
		LinkedHashMap<String, Integer> srt = new LinkedHashMap<String, Integer>();
		int l = str.length();
		StringBuilder builder = new StringBuilder();
		int prev = 0;
		for (int i = str.indexOf("{{"); i >= 0; i = str.indexOf("{{", prev)) {
			if (prev < i - 1) {
				builder.append(str.substring(prev, i).trim());
				if (i > 0 && Character.isWhitespace(str.charAt(i - 1)))
					builder.append(" ");
			}
			i += 2;

			// prev = str.indexOf("}}", i);

			// prev = prev < 0 ? str.length() - 2 : prev;

			char prevChar = 0;
			int co = 0;
			int pos = i;
			for (int m = i - 2; m < str.length(); m++) {

				char charAt = str.charAt(m);
				if (charAt == '{' && prevChar == '{') {
					co++;
				}
				if (charAt == '}' && prevChar == '}') {
					co--;
					if (co == 0) {
						pos = m;
						break;
					}
				}
				prevChar = charAt;
			}
			prev = pos + 1;
			String wholeTemplateString = str.substring(i - 2, prev);

			int ind = wholeTemplateString.indexOf("|", 0);
			int c = 0;
			int cm=0;
			for (int a = 0; a < wholeTemplateString.length(); a++) {
				if (wholeTemplateString.charAt(a) == '=') {
					c++;
				}
				if (wholeTemplateString.charAt(a) == '|') {
					cm++;
				}
			}
			if (c > 3&&cm>3&&ind>0) {
				String templateName = wholeTemplateString.substring(2, ind)
						.toLowerCase().trim();
				StringBuilder bm=new StringBuilder();
				int p=0;
				for (int a=0;a<templateName.length();a++){
					char charAt = templateName.charAt(a);
					if (charAt==' '){
						if (p>0){
							continue;
						}
						p=1;						
					}
					else{
						p=0;
					}
					if (charAt=='<'){
						break;						
					}
					if (templateName.charAt(a)=='/'){
						break;						
					}
					if (templateName.charAt(a)=='?'){
						break;						
					}
					bm.append(templateName.charAt(a));
				}
				templateName=bm.toString().trim().replace(' ','_');
				
				if (!toIgnore.contains(templateName)
						&& !templateName.startsWith("link")
						&& !templateName.startsWith("portal")
						&& !templateName.startsWith("#")
						&& !templateName.contains("{")
						&& !templateName.startsWith("cite")
						&& !templateName.startsWith("pp-move")
						&& !templateName.startsWith("lang")) {
					if (srt.containsKey(templateName)) {
						continue;
					}
					Integer integer = srt.get(templateName);
					if (integer == null) {
						integer = 0;
					}

					integer += 1;
					srt.put(templateName, integer);
				}
			}
		}
		return srt;
	}
}
